package main

import (
	"context"
	"database/sql"
	"encoding/json"
	"errors"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
	"sync"
	"time"

	clipboard2 "github.com/atotto/clipboard"

	_ "github.com/mattn/go-sqlite3"

	"golang.design/x/clipboard"
)

type QuestionAnswer struct {
	Question string
	Answer   []string
}

func main() {
	startViewer()
	queryLoop()
}

func queryLoop() {
	changed := waitClipboard()

	for v := range changed {
		s := string(v)
		ret, err := getAnswers(s)
		if err != nil {
			fmt.Println(err.Error())
		}
		showAnswers(ret)

	}

}

func getAnswers(key string) ([]QuestionAnswer, error) {
	if key == "" {
		return nil, errors.New("Empty Key Word")
	}
	var ret = []QuestionAnswer{}
	db, err := sql.Open("sqlite3", "data.db")
	if err != nil {
		return nil, err
	}
	defer db.Close()
	rows, err := db.Query("SELECT question,answers FROM answers where question like ?;", "%"+key+"%")
	if err != nil {
		fmt.Println(err.Error())
		return nil, err
	}
	for {
		if rows.Next() == false {
			break
		}
		var question, answers string
		err = rows.Scan(&question, &answers)
		if err != nil {
			fmt.Println(err.Error())
			break
		}
		var answers_v []string
		err = json.Unmarshal([]byte(answers), &answers_v)
		if err != nil {
			fmt.Println(err.Error())
			break
		}

		v := QuestionAnswer{Question: question, Answer: answers_v}
		ret = append(ret, v)
	}

	return ret, rows.Close()
}

func waitClipboard() chan string {
	ret := make(chan string, 1)

	go func() {
		if runtime.GOOS == "linux" {
			err := clipboard.Init()
			if err != nil {
				panic(err)
			}
			changed := clipboard.Watch(context.Background(), clipboard.FmtText)
			for v := range changed {
				s := string(v)
				ret <- s
			}
		} else if runtime.GOOS == "windows" {
			var lastBuf string
			for {
				buf, _ := clipboard2.ReadAll()

				if strings.Compare(lastBuf, buf) == 0 {
					time.Sleep(time.Millisecond * 500)
				} else {
					lastBuf = buf
					ret <- buf
				}
			}
		}
	}()

	return ret
}

var once sync.Once

func startViewer() {
	once.Do(func() {
		go func() {
			for {
				wd, err := os.Getwd()
				if err != nil {
					return
				}
				exe := filepath.Join(wd, "viewer")
				if runtime.GOOS == "windows" {
					exe = exe + ".exe"
				}

				cmd := exec.Command(exe)
				cmd.Run()
				cmd.Wait()
			}

		}()
	})
}
